//
// Created by heqian on 17-8-16.
//

#include "HttpClient.h"
#include <stdlib.h>

using namespace std;

namespace utils {
    HttpClient::HttpClient() :
            mPort(80) {

        mHead["Connection"] = "keep-alive";
        mHead["Pragma"] = "no-cache";
        mHead["Cache-Control"] = "no-cache";
        mHead["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
        mHead["Upgrade-Insecure-Requests"] = "1";
        mHead["User-Agent"] = "Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true";
        mHead["Content-Type"] = "application/x-www-form-urlencoded";
        mHead["Accept-Encoding"] = "gzip, deflate";
        mHead["Accept-Language"] = "zh-CN,zh;q=0.8";
    }

    void HttpClient::addHead(string &key, string &value) {
        mHead[key] = value;
    }

    const string &HttpClient::getBodyData() const {
        return mBodyData;
    }

    const string &HttpClient::getUrl() const {
        return mUrl;
    }

    void HttpClient::get(const string &mUrl) {
        HttpClient::mUrl = mUrl;
        mMethod = "GET";
        re(false);
    }

    const string &HttpClient::getData() const {
        return mData;
    }

    void HttpClient::setData(const char *data, int len) {
        HttpClient::mData.append(data, len);
    }

    void HttpClient::post(const string &mUrl) {
        HttpClient::mUrl = mUrl;
        mMethod = "POST";
        re(true);
    }

    void HttpClient::re(bool isPost) {
        parseHost(mUrl);

        char temp[1024];
        string head;
        head.append(mMethod).append(" /").append(mURLPart).append("  HTTP/1.1").append("\r\n");
        sprintf(temp, "%d", mPort);
        head.append("Host: ").append(mHost).append(":").append(temp).append("\r\n");
        if (isPost) {
            sprintf(temp, "%d", mData.length());
            head.append("Content-Length: ").append(temp).append("\r\n");
        }

        for (pair<const string, string> &item:mHead) {
            head.append(item.first).append(": ").append(item.second).append("\r\n");
        }
        head.append("\r\n");

        Socket socket;
        socket.Connect(mHost, mPort);
        socket.Send((char *) head.c_str(), head.length());
        if (isPost) {
            socket.Send((char *) mData.c_str(), mData.length());
        }

        int len, start, end, bodyStart, lenght = -1;
        string value;
        mBodyData.clear();

        while (0 < (len = socket.Recv(temp, 1024))) {
            mBodyData.append(temp, len);
            if (-1 == lenght) {
                bodyStart = mBodyData.find("\r\n\r\n");
                if (-1 < bodyStart) {
                    bodyStart += 4;

                    start = mBodyData.find("Content-Length: ") + 16;
                    end = mBodyData.find("\r\n", start);
                    value = mBodyData.substr(start, end - start);
                    lenght = atoi(value.c_str());
                }
            }

            if (len >= bodyStart + lenght) {
                mBodyData = mBodyData.substr(bodyStart, lenght - bodyStart);
            }
            break;
        };

        socket.Close();
    }

    void HttpClient::parseHost(string &basic) {
        int start = 0;
        int ends = 0;
        if (0 == basic.find("http://")) {
            start = 7;
            ends = basic.find("/", start);
        } else if (0 == basic.find("https://")) {
            start = 8;
            ends = basic.find("/", start);
        } else {
            ends = basic.find("/");
        }

        if (-1 == ends)
            ends = basic.length();

        mHost = basic.substr(start, ends - start);
        start = mHost.find(":");

        if (-1 != start) {
            mURLPart = mHost.substr(start + 1);
            mPort = atoi(mURLPart.c_str());
            mHost = mHost.substr(0, start);
        }
        if (basic.length() == ends)
            mURLPart = "";
        else
            mURLPart = basic.substr(ends + 1);
    }


}